<!-- HTML header for doxygen 1.8.13-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>MTB CAT1 Peripheral driver library: KeyScan      (KeyScan)</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><a href="http://www.cypress.com/"><img alt="Logo" src="IFXCYP_one-line.png"/></a></td>
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">MTB CAT1 Peripheral driver library</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('group__group__keyscan.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="summary">
<a href="#groups">API Reference</a>  </div>
  <div class="headertitle">
<div class="title">KeyScan (KeyScan)</div>  </div>
</div><!--header-->
<div class="contents">
<a name="details" id="details"></a><h2 class="groupheader">General Description</h2>
<p>MXKEYSCAN is a DEEPSLEEP peripheral IP that performs autonomous key-matrix scan and system notification. </p>
<p>Key processing detects both press and un-press actions, includes micro and macro de-bouncing filters and ghost key detection.</p>
<p>Configurable key-matrix size supports up to 20x8 keys. Up to 20 columns are driven as the output and up to 8 rows are processed as the input. Key actions are stored in the FIFO with interrupt notification available based on the FIFO threshold.</p>
<p>The Scan matrix support up to 8X20 matrix, maximum of 160 keys. Any key press will be translated into an index corresponding column and corresponding row. Before any key is pressed, the Key Matrix Scan Logic is disabled. Once a key press is detected by the Key Detection Logic, it will enable the gate for clock to drive the key Matrix Scan Logic for GPIO scanning. GPIO scanning is done one column at a time by driving each column "low" and reading from the row GPIO pins to find out which input is low. After the Key Scan Logic had scanned through the matrix for a specific number for debounce times configured by firmware though the configuration register, keycode representing the pressed key is pushed into the key FIFO for firmware to read and an interrupt to CPU will be generated. There are two types of debounce mechanisms build into this scan matrix block. The micro-debounce logic will provide a small debounce period to debounce the break type of mechanical vibration. The macro debounce logic will scan through the matrix for a number of times for qualify a key as being pressed.</p>
<p>Features:</p><ul>
<li>Ability to turn off it's clock if no keys pressed.</li>
<li>Sequential scanning of up to 160 keys in a 8X20 matrix</li>
<li>Programmable number of columns from 1 to 20.</li>
<li>Programmable number of rows from 1 to 8.</li>
<li>20-byte key-code buffer.</li>
<li>128-kHz clock allow scanning of full 160 key matrix in about 1.2ms.</li>
<li>Keys are buffered until host microcontroller has a chance to read it, or until overflow occurs.</li>
<li>Hardware debouncing and noise/glitch filtering.</li>
</ul>
<p>This driver provides the user an easy method for accessing KeyScan registers and provides some simple functionality for reading key index from keyscan FIFO.</p>
<p>The IP supports only Sequential PIN configuration. For Example if the user is configuring the IP for 4 pins (2 ROWS and 2 COLUMNs) the user is suggested to use ROWS 0,1 and COLUMNS 0,1. Interleaved ROWS and COLUMNS are not supported by the IP i.e. User should not configure ROW0 and ROW3 and COLUMN1 and COLUMN4 etc.</p>
<p>With every Key event, User receives the following information</p><ul>
<li>Key Code : The keyCode for the key press event detected. Keycode is calculated as ((no of rows * column num) + row num)</li>
<li>UP/DOWN flag : Whether the key event is for the key press or for the key release event.</li>
<li>Scan Cycle flag : It is toggled for every scan cycle in which a new event is queued. Use of this flag is optional. If used, it allows the consumer to determine whether an event is detected in the same scan cycle as the previous event or a different one. Note that this flag does not indicate any separation in time.</li>
</ul>
<div class="image">
<img src="keyscan_matrix.png" alt="keyscan_matrix.png" width="600px"/>
<div class="caption">
Keyscan Matrix</div></div>
 <p>Initialization:</p>
<p>The KeyScan driver initialization is according to the Options setup in the passed Config Struct. Several validations are done before the initialization and an error is returned if invalid Modes are requested.</p>
<p>KeyScan Configuration</p>
<ul>
<li>Enable/Disable ghost detection</li>
<li>Enable/Disable wakeup host MCU when key is detected.</li>
<li>Set the number of rows of key matrix</li>
<li>Set the no of columns of the key matrix.</li>
<li>Set the clock to stay on or gated of when no activity is detected.</li>
<li>Set macro down debounce count.</li>
<li>Set macro up debounce count.</li>
<li>Set micro debounce count.</li>
</ul>
<p>Application then registers for the callback. Driver notifies the user for any events in this callback function. </p><div class="fragment"><div class="line"></div><div class="line">    <a class="code" href="structcy__stc__ks__config__t.html">cy_stc_ks_config_t</a> keyscan_config =</div><div class="line">    {</div><div class="line">        .<a class="code" href="structcy__stc__ks__config__t.html#a4ea353cdc39783c95c29df47731f4ac1">macroDownDebCnt</a> = 3u,  </div><div class="line">        .macroUpDebCnt = 3u,    </div><div class="line">        .microDebCnt = 3u,      </div><div class="line">        .noofRows = 8u,         </div><div class="line">        .noofColumns = 20u,     </div><div class="line">        .ghostEnable = <span class="keyword">true</span>,    </div><div class="line">        .cpuWakeupEnable = <span class="keyword">true</span>,</div><div class="line">        .clkStayOn = <span class="keyword">true</span>       </div><div class="line">    };</div><div class="line"></div><div class="line">    <a class="code" href="group__group__keyscan__enums.html#ga63db7add05b9f273c43aac216af16d4b">cy_en_ks_status_t</a> status;</div><div class="line">    status = <a class="code" href="group__group__keyscan__functions.html#gaee762678f971e88e99b0a7eda63959df">Cy_Keyscan_Init</a>(MXKEYSCAN, &amp;keyscan_config, &amp;context);</div><div class="line">    <span class="keywordflow">if</span>(status != <a class="code" href="group__group__keyscan__enums.html#gga63db7add05b9f273c43aac216af16d4bad0ab5c35021d0615b1063492c23e1841">CY_KEYSCAN_SUCCESS</a>)</div><div class="line">    {</div><div class="line">        <span class="comment">/* Insert error handling */</span></div><div class="line">    }</div></div><!-- fragment --><p> Interrupt Handling</p>
<p>Keyscan has a dedicated interrupt keyscan_interrupt_IRQn</p>
<p>There are 2 type of interrupts that the software has to check when there is an interrupt</p><ul>
<li>MXKEYSCAN_INTR_KEY_EDGE_DONE : Used for waking up the system from deepsleep. This should be disabled when the MF clock is active.</li>
<li>MXKEYSCAN_INTR_FIFO_THRESH_DONE : For all key events</li>
<li>MXKEYSCAN_INTR_KEY_EDGE_DONE interrupt is mainly used for waking up the system from deepsleep. Applications register for this interrupt before going to deepsleep, then with key event MCU will be woken up.</li>
<li>MXKEYSCAN_INTR_FIFO_THRESH_DONE interrupt is triggered when there are key press/release events. In the active mode application should be registering only for this interrupt.</li>
</ul>
<div class="fragment"><div class="line">    <a class="code" href="group__group__keyscan__enums.html#ga63db7add05b9f273c43aac216af16d4b">cy_en_ks_status_t</a> status;</div><div class="line">    status = <a class="code" href="group__group__keyscan__functions.html#gaee762678f971e88e99b0a7eda63959df">Cy_Keyscan_Init</a>(MXKEYSCAN, &amp;keyscan_config, &amp;context);</div><div class="line">    <span class="keywordflow">if</span>(status != <a class="code" href="group__group__keyscan__enums.html#gga63db7add05b9f273c43aac216af16d4bad0ab5c35021d0615b1063492c23e1841">CY_KEYSCAN_SUCCESS</a>)</div><div class="line">    {</div><div class="line">         <span class="comment">/* Insert error handling */</span></div><div class="line">    }</div><div class="line">    <span class="comment">/* User has to register for callback. Driver notifies the user for any events in this callback function. */</span></div><div class="line">    status = <a class="code" href="group__group__keyscan__functions.html#ga52e9c93682fa82711dbf1be652033d0d">Cy_Keyscan_Register_Callback</a>(key_detected_callback, &amp;context);</div><div class="line">    <span class="keywordflow">if</span>(status != <a class="code" href="group__group__keyscan__enums.html#gga63db7add05b9f273c43aac216af16d4bad0ab5c35021d0615b1063492c23e1841">CY_KEYSCAN_SUCCESS</a>)</div><div class="line">    {</div><div class="line">         <span class="comment">/* Insert error handling */</span></div><div class="line">    }</div><div class="line"></div><div class="line">    status = <a class="code" href="group__group__keyscan__functions.html#gab15fd633e448e5f75ff3f3a7880a9670">Cy_Keyscan_SetInterruptMask</a>(MXKEYSCAN, <a class="code" href="group__group__keyscan__intr__mask__macro.html#gabaf6c48f537039c42f3cd554fbead9ec">MXKEYSCAN_INTR_FIFO_THRESH_DONE</a>);</div><div class="line">    <span class="keywordflow">if</span>(status != <a class="code" href="group__group__keyscan__enums.html#gga63db7add05b9f273c43aac216af16d4bad0ab5c35021d0615b1063492c23e1841">CY_KEYSCAN_SUCCESS</a>)</div><div class="line">    {</div><div class="line">         <span class="comment">/* Insert error handling */</span></div><div class="line">    }</div></div><!-- fragment --><p> Applications have to call Cy_Keyscan_Interrupt_Handler function from keyscan interrupt handler. Applications will be notified of any key events through the registered callback. Applications have to read the events in the callback function by calling Cy_Keyscan_GetNextEvent function in a loop till the return value is CY_KEYSCAN_EVENT_NONE. With every Key event, User receives the following information</p><ul>
<li>Key Code : The keyCode for the key press event detected. Keycode is calculated as ((no of rows * column num) + row num)</li>
<li>UP/DOWN flag : Whether the key event is for the key press or for the key release.</li>
<li>Scan Cycle flag : It is toggled for every scan cycle in which a new event is queued. Use of this flag is optional. If used, it allows the consumer to determine whether an event is detected in the same scan cycle as the previous event or a different one. Note that this flag does not indicate any separation in time.</li>
</ul>
<div class="fragment"><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> ** Applications have to call Cy_Keyscan_Interrupt_Handler function from keyscan interrupt handler.</span></div><div class="line"><span class="comment"> ** Applications will be notified of any key events through the registered callback.</span></div><div class="line"><span class="comment"> ** Applications have to read the events in the callback function by calling Cy_Keyscan_GetNextEvent function in a loop till</span></div><div class="line"><span class="comment"> ** the return value is CY_KEYSCAN_EVENT_NONE.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keywordtype">void</span> keyscan_intHandler(<span class="keywordtype">void</span>)</div><div class="line">{</div><div class="line">    <a class="code" href="group__group__keyscan__enums.html#ga63db7add05b9f273c43aac216af16d4b">cy_en_ks_status_t</a> status;</div><div class="line">    uint32_t int_status;</div><div class="line">    <a class="code" href="group__group__keyscan__functions.html#gaafe690c5c55275e002675833358efc71">Cy_Keyscan_GetInterruptMaskedStatus</a>(MXKEYSCAN, &amp;int_status);</div><div class="line">    <span class="keywordflow">if</span>(0UL != (<a class="code" href="group__group__keyscan__intr__mask__macro.html#gabaf6c48f537039c42f3cd554fbead9ec">MXKEYSCAN_INTR_FIFO_THRESH_DONE</a> &amp; int_status))</div><div class="line">    {</div><div class="line">       status = <a class="code" href="group__group__keyscan__functions.html#gac0949bdeeec1076c259f327b5be4766c">Cy_Keyscan_Interrupt_Handler</a>(MXKEYSCAN, &amp;context);</div><div class="line">       <span class="keywordflow">if</span>(<a class="code" href="group__group__keyscan__enums.html#gga63db7add05b9f273c43aac216af16d4bad0ab5c35021d0615b1063492c23e1841">CY_KEYSCAN_SUCCESS</a> != status)</div><div class="line">       {</div><div class="line">            <span class="comment">// Keyscan interrupt handler failed </span></div><div class="line">       }</div><div class="line">    }</div><div class="line">    <span class="keywordflow">else</span></div><div class="line">    {</div><div class="line">        <a class="code" href="group__group__keyscan__functions.html#gab0697bc91ec30ec625080f2e36d8f76f">Cy_Keyscan_ClearInterrupt</a>(MXKEYSCAN, <a class="code" href="group__group__keyscan__intr__mask__macro.html#ga203e1a386d3c094322980c053cb4d5f9">MXKEYSCAN_INTR_KEY_EDGE_DONE</a>);</div><div class="line">    }</div><div class="line"></div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> key_detected_callback(<span class="keywordtype">void</span>)</div><div class="line">{</div><div class="line">    <a class="code" href="group__group__keyscan__enums.html#ga63db7add05b9f273c43aac216af16d4b">cy_en_ks_status_t</a> status;</div><div class="line">    <a class="code" href="structcy__stc__key__event.html">cy_stc_key_event</a> kevent;</div><div class="line">    uint8_t keyCode, scanCycle, upDownFlag;</div><div class="line">    <span class="keywordtype">bool</span> events_pending;</div><div class="line">    <a class="code" href="group__group__keyscan__functions.html#ga2d9772cf7639507551f8719b61ee149a">Cy_Keyscan_EventsPending</a>(MXKEYSCAN, &amp;events_pending, &amp;context);</div><div class="line">    <span class="keywordflow">while</span> (events_pending)</div><div class="line">    {</div><div class="line">        status = <a class="code" href="group__group__keyscan__functions.html#ga112645238ff1a8fbe2babf37ececa928">Cy_Keyscan_GetNextEvent</a>(MXKEYSCAN, &amp;kevent, &amp;context);</div><div class="line">        <span class="keywordflow">if</span>(status != <a class="code" href="group__group__keyscan__enums.html#gga63db7add05b9f273c43aac216af16d4bad0ab5c35021d0615b1063492c23e1841">CY_KEYSCAN_SUCCESS</a>)</div><div class="line">        {</div><div class="line">            <span class="comment">// Keyscan get next event failed </span></div><div class="line">        }</div><div class="line">        <span class="comment">/* Check value of keycode for the corresponding key being pressed</span></div><div class="line"><span class="comment">           Keycode is calculated as ((no of rows * column num) + row num) */</span></div><div class="line">        keyCode = kevent.<a class="code" href="structcy__stc__key__event.html#a380b32448606828dab08e812bc3177f7">keyCode</a>;</div><div class="line">        scanCycle = kevent.<a class="code" href="structcy__stc__key__event.html#a4dfca39b0e4b645e4f4aa3c4ba346dc2">scanCycleFlag</a>;</div><div class="line">        upDownFlag = kevent.<a class="code" href="structcy__stc__key__event.html#a09f7d1c2aeb58ae2e29556a7933c7c79">upDownFlag</a>;</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span>(keyCode == <a class="code" href="group__group__keyscan__enums.html#gga3e52483d024a86b66d31e61c83ed4751a5226620ddbc8a578dd0de50c7e6f4728">KEYSCAN_KEYCODE_ROLLOVER</a>)</div><div class="line">        {</div><div class="line">            <span class="comment">// ROLLOVER KEY DETECTED</span></div><div class="line">        }</div><div class="line">        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(keyCode == <a class="code" href="group__group__keyscan__enums.html#gga3e52483d024a86b66d31e61c83ed4751a2ef0b0d0f231e64c1eff96564dcf1d9a">KEYSCAN_KEYCODE_END_OF_SCAN_CYCLE</a>)</div><div class="line">        {</div><div class="line">            <span class="comment">// End of Scan Cycle event. Added by driver when an event is occurred in different scan cycle.</span></div><div class="line">            <a class="code" href="group__group__keyscan__functions.html#ga2d9772cf7639507551f8719b61ee149a">Cy_Keyscan_EventsPending</a>(MXKEYSCAN, &amp;events_pending, &amp;context);</div><div class="line">            <span class="keywordflow">continue</span>;</div><div class="line">        }</div><div class="line">        <a class="code" href="group__group__keyscan__functions.html#ga2d9772cf7639507551f8719b61ee149a">Cy_Keyscan_EventsPending</a>(MXKEYSCAN, &amp;events_pending, &amp;context);</div><div class="line">        (void)keyCode;</div><div class="line">        (void)scanCycle;</div><div class="line">        (void)upDownFlag;</div><div class="line">    }</div><div class="line">}</div></div><!-- fragment --><p> Handling DeepSleep</p>
<p>Following are the points users of keyscan have to handle in their code.</p><ul>
<li>Normal DeepSleep configuration is MFO clock disabled, LF Clock enabled and edge interrupt enabled.</li>
<li>When edge interrupt occurs, configure MFO to remain enabled in Deepsleep, disable edge interrupt, and go back to Deepsleep.</li>
<li>Whenever MFO clock is enabled in the Deepsleep and edge interrupt is disabled, user should start a timer. Every time a key event is detected, user should restart the timer. When timer expires (and/or all keys are considered up), user should go back to Deepsleep with MFO disabled and edge interrupt enabled.</li>
</ul>
<h1><a class="anchor" id="group_keyscan_changelog"></a>
Changelog</h1>
<table class="doxtable">
<tr>
<th>Version</th><th>Changes</th><th>Reason for Change </th></tr>
<tr>
<td>1.0 </td><td>Initial version </td><td></td></tr>
</table>
<ul>
<li></li>
</ul>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="groups"></a>
API Reference</h2></td></tr>
<tr class="memitem:group__group__keyscan__macro"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group__keyscan__macro.html">Macros</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:group__group__keyscan__functions"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group__keyscan__functions.html">Functions</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:group__group__keyscan__data__structures"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group__keyscan__data__structures.html">Data Structures</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:group__group__keyscan__enums"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__group__keyscan__enums.html">Enumerated Types</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part
<div id="nav-path" class="navpath">
    <ul>
        <li class="footer">
            Generated for <b>MTB CAT1 Peripheral driver library</b> by <b>Cypress Semiconductor Corporation</b>.
            All rights reserved.
        </li>
    </ul>
</div>
-->
</body>
</html>
